"""
实验报告批改系统 - 主界面
Author: AI Assistant
Date: 2025-01-09
"""
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, scrolledtext
import threading
import json
import os
from pathlib import Path
from datetime import datetime
import logging
from typing import Optional, Dict, Any
import sv_ttk

# 导入现有模块
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(__file__)))

from processors.doc_process import DocumentProcessor
from utils.excel_recorder import ExcelRecorder
from utils.file_utils import setup_output_directory
from utils.models import LLMClient, ApiClient
from gui.analysis_window import open_analysis_window


class MainWindow:
    def __init__(self, root):
        self.root = root
        self.root.title("实验报告批改系统 v1.0")
        self.root.geometry("1200x800")
        self.root.minsize(1000, 700)
        
        # 配置变量
        self.config = self.load_config()
        self.is_processing = False
        self.processing_thread = None
        self.current_theme = "light"  # 当前主题
        
        # 设置样式
        self.setup_styles()
        
        # 创建界面
        self.create_widgets()
        self.setup_logging()
        
    def setup_styles(self):
        """设置界面样式"""
        # 使用 Sun Valley 主题
        sv_ttk.set_theme(self.current_theme)
        
        style = ttk.Style()
        
        # 根据主题定义颜色方案
        if self.current_theme == "light":
            self.colors = {
                'primary': '#0078D4',      # 主色调 - 现代蓝
                'secondary': '#8764B8',    # 次要色 - 现代紫
                'success': '#107C10',      # 成功色 - 现代绿
                'warning': '#D13438',      # 警告色 - 现代红
                'background': '#FFFFFF',   # 背景色 - 白色
                'surface': '#F3F2F1',      # 表面色 - 浅灰
                'text': '#323130',         # 文字色 - 深灰
                'text_light': '#605E5C',   # 浅文字色 - 中灰
                'border': '#E1DFDD',       # 边框色 - 浅灰
                'accent': '#0078D4'        # 强调色 - 现代蓝
            }
        else:  # dark theme
            self.colors = {
                'primary': '#60CDFF',      # 主色调 - 亮蓝
                'secondary': '#B4A7D6',    # 次要色 - 亮紫
                'success': '#6FBD44',      # 成功色 - 亮绿
                'warning': '#FF6B6B',      # 警告色 - 亮红
                'background': '#1E1E1E',   # 背景色 - 深色
                'surface': '#2D2D30',      # 表面色 - 深灰
                'text': '#FFFFFF',         # 文字色 - 白色
                'text_light': '#CCCCCC',   # 浅文字色 - 浅灰
                'border': '#3E3E42',       # 边框色 - 深灰
                'accent': '#60CDFF'        # 强调色 - 亮蓝
            }
        
        # 配置根窗口样式
        self.root.configure(bg=self.colors['background'])
        
        # 配置标题样式
        style.configure('Title.TLabel', 
                       font=('Microsoft YaHei', 18, 'bold'),
                       foreground=self.colors['primary'],
                       background=self.colors['background'])
        
        # 配置标题框架样式
        style.configure('Title.TFrame', 
                       background=self.colors['background'],
                       relief='flat')
        
        # 配置面板标题样式
        style.configure('PanelTitle.TLabel', 
                       font=('Microsoft YaHei', 13, 'bold'),
                       foreground=self.colors['text'],
                       background=self.colors['surface'])
        
        # 配置面板框架样式
        style.configure('Panel.TFrame', 
                       background=self.colors['surface'],
                       relief='solid',
                       borderwidth=1)
        
        # 配置标签样式
        style.configure('Heading.TLabel', 
                       font=('Microsoft YaHei', 11, 'bold'),
                       foreground=self.colors['text'],
                       background=self.colors['surface'])
        
        style.configure('Info.TLabel', 
                       font=('Microsoft YaHei', 10),
                       foreground=self.colors['text_light'],
                       background=self.colors['surface'])
        
        # 配置按钮样式
        style.configure('Primary.TButton',
                       font=('Microsoft YaHei', 10, 'bold'),
                       foreground='white',
                       background=self.colors['primary'],
                       relief='flat',
                       padding=(15, 8))
        
        style.map('Primary.TButton',
                 background=[('active', self.colors['secondary']),
                           ('pressed', self.colors['accent'])])
        
        style.configure('Secondary.TButton',
                       font=('Microsoft YaHei', 10),
                       foreground=self.colors['text'],
                       background=self.colors['surface'],
                       relief='solid',
                       borderwidth=1,
                       padding=(10, 6))
        
        style.map('Secondary.TButton',
                 background=[('active', self.colors['background']),
                           ('pressed', self.colors['border'])])
        
        # 配置输入框样式
        style.configure('Custom.TEntry',
                       font=('Microsoft YaHei', 10),
                       fieldbackground=self.colors['surface'],
                       borderwidth=1,
                       relief='solid',
                       padding=5)
        
        # 配置组合框样式
        style.configure('Custom.TCombobox',
                       font=('Microsoft YaHei', 10),
                       fieldbackground=self.colors['surface'],
                       borderwidth=1,
                       relief='solid',
                       padding=5)
        
        # 配置进度条样式
        style.configure('Custom.Horizontal.TProgressbar',
                       background=self.colors['primary'],
                       troughcolor=self.colors['border'],
                       borderwidth=0,
                       lightcolor=self.colors['primary'],
                       darkcolor=self.colors['primary'])
        
        # 配置标签框架样式
        style.configure('Custom.TLabelframe',
                       background=self.colors['surface'],
                       foreground=self.colors['text'],
                       font=('Microsoft YaHei', 11, 'bold'),
                       relief='solid',
                       borderwidth=1)
        
        style.configure('Custom.TLabelframe.Label',
                       background=self.colors['surface'],
                       foreground=self.colors['primary'],
                       font=('Microsoft YaHei', 11, 'bold'))
        
    def load_config(self) -> Dict[str, Any]:
        """加载配置文件"""
        config_path = Path(__file__).parent.parent / 'config.json'
        try:
            if config_path.exists():
                with open(config_path, 'r', encoding='utf-8') as f:
                    return json.load(f)
        except Exception as e:
            print(f"加载配置文件失败: {e}")
        
        # 默认配置
        return {
            "input_directory": "",
            "output_directory": "",
            "comment_author": "教师",
            "required_sections": ["实验准备", "实验内容", "实验小结"],
            "system_prompt": "",
            "model_type": "deepseek",
            "api_key": "",
            "base_url": "https://api.deepseek.com/v1"
        }
    
    def save_config(self):
        """保存配置文件"""
        # 先更新配置变量
        self.update_config()
        
        config_path = Path(__file__).parent.parent / 'config.json'
        try:
            with open(config_path, 'w', encoding='utf-8') as f:
                json.dump(self.config, f, ensure_ascii=False, indent=4)
            self.logger.info("配置保存成功")
            messagebox.showinfo("成功", "配置已保存")
        except Exception as e:
            messagebox.showerror("错误", f"保存配置失败: {e}")
            self.logger.error(f"保存配置失败: {e}")
    
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = ttk.Frame(self.root, style='Title.TFrame', padding="20")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 配置网格权重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.columnconfigure(0, weight=1)
        main_frame.columnconfigure(1, weight=1)
        main_frame.columnconfigure(2, weight=1)
        
        # 标题区域
        title_frame = ttk.Frame(main_frame, style='Title.TFrame')
        title_frame.grid(row=0, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(0, 25))
        title_frame.columnconfigure(0, weight=1)
        
        # 副标题
        subtitle_label = ttk.Label(title_frame, text="AI智能批改 · 批量处理 · 自动评分", 
                                  font=('Microsoft YaHei', 12), 
                                  foreground=self.colors['text_light'],
                                  background=self.colors['background'])
        subtitle_label.grid(row=1, column=0)
        
        # 创建各个面板 - 使用三列布局
        self.create_model_panel(main_frame, 1, 0)
        self.create_directory_panel(main_frame, 1, 1)
        self.create_system_prompt_panel(main_frame, 1, 2)
        self.create_settings_panel(main_frame, 2, 0)
        self.create_control_panel(main_frame, 2, 1)
        # 第三列第二行留空，让系统提示词面板占据更多空间
        
        # 进度和日志面板并列显示
        self.create_progress_panel(main_frame, 3, 0)
        self.create_log_panel(main_frame, 3, 1, columnspan=2)
        
    def create_model_panel(self, parent, row, column):
        """创建模型配置面板"""
        # 模型面板框架
        model_frame = ttk.LabelFrame(parent, text="🤖 模型配置", style='Custom.TLabelframe', padding="15")
        model_frame.grid(row=row, column=column, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 15), padx=(0, 10))
        model_frame.columnconfigure(1, weight=1)
        
        # 模型类型选择
        ttk.Label(model_frame, text="模型类型:", style='Heading.TLabel').grid(row=0, column=0, sticky=tk.W, padx=(0, 10), pady=(0, 5))
        self.model_type_var = tk.StringVar(value=self.config.get('model_type', 'deepseek'))
        model_combo = ttk.Combobox(model_frame, textvariable=self.model_type_var, 
                                 values=['deepseek', 'ollama'], state='readonly', 
                                 style='Custom.TCombobox', width=20)
        model_combo.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=(0, 10), pady=(0, 5))
        
        # API密钥
        ttk.Label(model_frame, text="API密钥:", style='Heading.TLabel').grid(row=1, column=0, sticky=tk.W, padx=(0, 10), pady=(10, 5))
        self.api_key_var = tk.StringVar(value=self.config.get('api_key', ''))
        api_key_entry = ttk.Entry(model_frame, textvariable=self.api_key_var, show="*", 
                                 style='Custom.TEntry', width=30)
        api_key_entry.grid(row=1, column=1, sticky=(tk.W, tk.E), padx=(0, 10), pady=(10, 5))
        
        # 基础URL
        ttk.Label(model_frame, text="基础URL:", style='Heading.TLabel').grid(row=2, column=0, sticky=tk.W, padx=(0, 10), pady=(10, 5))
        self.base_url_var = tk.StringVar(value=self.config.get('base_url', 'https://api.deepseek.com/v1'))
        base_url_entry = ttk.Entry(model_frame, textvariable=self.base_url_var, 
                                  style='Custom.TEntry', width=30)
        base_url_entry.grid(row=2, column=1, sticky=(tk.W, tk.E), padx=(0, 10), pady=(10, 5))
        
    def create_directory_panel(self, parent, row, column):
        """创建目录配置面板"""
        # 目录面板框架
        dir_frame = ttk.LabelFrame(parent, text="📁 目录配置", style='Custom.TLabelframe', padding="15")
        dir_frame.grid(row=row, column=column, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 15), padx=(5, 5))
        dir_frame.columnconfigure(1, weight=1)
        
        # 报告输入目录
        ttk.Label(dir_frame, text="报告输入目录:", style='Heading.TLabel').grid(row=0, column=0, sticky=tk.W, padx=(0, 10), pady=(0, 5))
        self.input_dir_var = tk.StringVar(value=self.config.get('input_directory', ''))
        input_dir_frame = ttk.Frame(dir_frame)
        input_dir_frame.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=(0, 10), pady=(0, 5))
        input_dir_frame.columnconfigure(0, weight=1)
        ttk.Entry(input_dir_frame, textvariable=self.input_dir_var, style='Custom.TEntry').grid(row=0, column=0, sticky=(tk.W, tk.E), padx=(0, 5))
        ttk.Button(input_dir_frame, text="📂", command=self.browse_input_dir, 
                  style='Secondary.TButton', width=3).grid(row=0, column=1)
        
        # 报告输出目录
        ttk.Label(dir_frame, text="报告输出目录:", style='Heading.TLabel').grid(row=1, column=0, sticky=tk.W, padx=(0, 10), pady=(10, 5))
        self.output_dir_var = tk.StringVar(value=self.config.get('output_directory', ''))
        output_dir_frame = ttk.Frame(dir_frame)
        output_dir_frame.grid(row=1, column=1, sticky=(tk.W, tk.E), padx=(0, 10), pady=(10, 5))
        output_dir_frame.columnconfigure(0, weight=1)
        ttk.Entry(output_dir_frame, textvariable=self.output_dir_var, style='Custom.TEntry').grid(row=0, column=0, sticky=(tk.W, tk.E), padx=(0, 5))
        ttk.Button(output_dir_frame, text="📂", command=self.browse_output_dir, 
                  style='Secondary.TButton', width=3).grid(row=0, column=1)
        
        # 文件统计信息
        ttk.Label(dir_frame, text="文件统计:", style='Heading.TLabel').grid(row=2, column=0, sticky=tk.W, padx=(0, 10), pady=(10, 5))
        self.file_stats_label = ttk.Label(dir_frame, text="未选择目录", style='Info.TLabel')
        self.file_stats_label.grid(row=2, column=1, sticky=tk.W, padx=(0, 10), pady=(10, 5))
        
        # 刷新统计按钮
        ttk.Button(dir_frame, text="🔄 刷新统计", command=self.refresh_file_stats, 
                  style='Secondary.TButton').grid(row=3, column=0, columnspan=2, pady=(10, 0), sticky=(tk.W, tk.E))
        
    def create_system_prompt_panel(self, parent, row, column):
        """创建系统提示词面板"""
        # 系统提示词面板框架
        prompt_frame = ttk.LabelFrame(parent, text="📝 系统提示词", style='Custom.TLabelframe', padding="15")
        prompt_frame.grid(row=row, column=column, rowspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 15), padx=(5, 0))
        prompt_frame.columnconfigure(0, weight=1)
        prompt_frame.rowconfigure(1, weight=1)
        
        # 提示词说明
        info_label = ttk.Label(prompt_frame, text="配置AI批改的评分标准和规则", style='Info.TLabel')
        info_label.grid(row=0, column=0, sticky=tk.W, pady=(0, 10))
        
        # 系统提示词文本框
        self.system_prompt_text = scrolledtext.ScrolledText(prompt_frame, height=8, width=40,
                                                           font=('Microsoft YaHei', 9),
                                                           wrap=tk.WORD,
                                                           bg=self.colors['surface'],
                                                           fg=self.colors['text'],
                                                           insertbackground=self.colors['text'],
                                                           selectbackground=self.colors['primary'],
                                                           selectforeground='white')
        self.system_prompt_text.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
        self.system_prompt_text.insert('1.0', self.config.get('system_prompt', ''))
        
        # 操作按钮框架
        button_frame = ttk.Frame(prompt_frame)
        button_frame.grid(row=2, column=0, sticky=(tk.W, tk.E), pady=(0, 0))
        button_frame.columnconfigure(0, weight=1)
        button_frame.columnconfigure(1, weight=1)
        
        # 清空按钮
        ttk.Button(button_frame, text="🗑️ 清空", command=self.clear_system_prompt, 
                  style='Secondary.TButton').grid(row=0, column=0, padx=(0, 5), sticky=(tk.W, tk.E))
        
        # 重置按钮
        ttk.Button(button_frame, text="🔄 重置", command=self.reset_system_prompt, 
                  style='Secondary.TButton').grid(row=0, column=1, padx=(5, 0), sticky=(tk.W, tk.E))
        
    def create_settings_panel(self, parent, row, column):
        """创建设置面板"""
        # 设置面板框架
        settings_frame = ttk.LabelFrame(parent, text="⚙️ 批改设置", style='Custom.TLabelframe', padding="15")
        settings_frame.grid(row=row, column=column, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 15), padx=(5, 5))
        settings_frame.columnconfigure(1, weight=1)
        
        # 评阅人
        ttk.Label(settings_frame, text="评阅人:", style='Heading.TLabel').grid(row=0, column=0, sticky=tk.W, padx=(0, 10), pady=(0, 5))
        self.comment_author_var = tk.StringVar(value=self.config.get('comment_author', '教师'))
        ttk.Entry(settings_frame, textvariable=self.comment_author_var, 
                 style='Custom.TEntry', width=25).grid(row=0, column=1, sticky=tk.W, padx=(0, 10), pady=(0, 5))
        
        # 必需章节
        ttk.Label(settings_frame, text="必需章节:", style='Heading.TLabel').grid(row=1, column=0, sticky=(tk.W, tk.N), padx=(0, 10), pady=(10, 5))
        self.required_sections_text = scrolledtext.ScrolledText(settings_frame, height=4, width=40,
                                                               font=('Microsoft YaHei', 9),
                                                               wrap=tk.WORD,
                                                               bg=self.colors['surface'],
                                                               fg=self.colors['text'],
                                                               insertbackground=self.colors['text'],
                                                               selectbackground=self.colors['primary'],
                                                               selectforeground='white')
        self.required_sections_text.grid(row=1, column=1, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(0, 10), pady=(10, 5))
        sections = self.config.get('required_sections', ['实验准备', '实验内容', '实验小结'])
        self.required_sections_text.insert('1.0', '\n'.join(sections))
        
    def create_control_panel(self, parent, row, column):
        """创建控制面板"""
        # 控制面板框架
        control_frame = ttk.LabelFrame(parent, text="🎮 控制面板", style='Custom.TLabelframe', padding="15")
        control_frame.grid(row=row, column=column, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 15), padx=(5, 5))
        control_frame.columnconfigure(0, weight=1)
        
        # 第一行按钮框架
        button_frame1 = ttk.Frame(control_frame)
        button_frame1.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 8))
        button_frame1.columnconfigure(0, weight=1)
        button_frame1.columnconfigure(1, weight=1)
        
        # 第二行按钮框架
        button_frame2 = ttk.Frame(control_frame)
        button_frame2.grid(row=1, column=0, sticky=(tk.W, tk.E), pady=(0, 8))
        button_frame2.columnconfigure(0, weight=1)
        button_frame2.columnconfigure(1, weight=1)
        
        # 第三行按钮框架
        button_frame3 = ttk.Frame(control_frame)
        button_frame3.grid(row=2, column=0, sticky=(tk.W, tk.E))
        button_frame3.columnconfigure(0, weight=1)
        
        # 第一行：开始和停止批改
        self.start_button = ttk.Button(button_frame1, text="🚀 开始批改", command=self.start_processing, 
                                     style='Secondary.TButton')
        self.start_button.grid(row=0, column=0, padx=(0, 5), sticky=(tk.W, tk.E))
        
        self.stop_button = ttk.Button(button_frame1, text="⏹️ 停止批改", command=self.stop_processing, 
                                    state='disabled', style='Secondary.TButton')
        self.stop_button.grid(row=0, column=1, padx=(5, 0), sticky=(tk.W, tk.E))
        
        # 第二行：保存配置和分析报告
        ttk.Button(button_frame2, text="💾 保存配置", command=self.save_config, 
                  style='Secondary.TButton').grid(row=0, column=0, padx=(0, 5), sticky=(tk.W, tk.E))
        
        ttk.Button(button_frame2, text="📊 分析报告", command=self.open_analysis_window, 
                  style='Secondary.TButton').grid(row=0, column=1, padx=(5, 0), sticky=(tk.W, tk.E))
        
        # 第三行：主题切换按钮
        theme_text = "🌙 深色主题" if self.current_theme == "light" else "☀️ 浅色主题"
        ttk.Button(button_frame3, text=theme_text, command=self.toggle_theme, 
                  style='Secondary.TButton').grid(row=0, column=0, sticky=(tk.W, tk.E))
        
    def create_progress_panel(self, parent, row, column=0, columnspan=1):
        """创建进度面板"""
        # 进度面板框架
        progress_frame = ttk.LabelFrame(parent, text="📈 处理进度", style='Custom.TLabelframe', padding="15")
        progress_frame.grid(row=row, column=column, columnspan=columnspan, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 15), padx=(0, 5))
        progress_frame.columnconfigure(0, weight=1)
        progress_frame.rowconfigure(0, weight=1)
        parent.rowconfigure(row, weight=1)
        
        # 进度条
        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(progress_frame, variable=self.progress_var, 
                                          maximum=100, style='Custom.Horizontal.TProgressbar')
        self.progress_bar.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # 进度标签
        self.progress_label = ttk.Label(progress_frame, text="🟢 准备就绪", style='Info.TLabel')
        self.progress_label.grid(row=1, column=0, sticky=tk.W)
        
        # 统计信息
        self.stats_label = ttk.Label(progress_frame, text="", style='Info.TLabel')
        self.stats_label.grid(row=2, column=0, sticky=tk.W, pady=(5, 0))
        
        # 状态指示器
        status_frame = ttk.Frame(progress_frame)
        status_frame.grid(row=3, column=0, sticky=(tk.W, tk.E), pady=(10, 0))
        status_frame.columnconfigure(0, weight=1)
        
        # 处理状态
        self.status_label = ttk.Label(status_frame, text="状态: 空闲", style='Info.TLabel')
        self.status_label.grid(row=0, column=0, sticky=tk.W)
        
        # 时间信息
        self.time_label = ttk.Label(status_frame, text="", style='Info.TLabel')
        self.time_label.grid(row=0, column=1, sticky=tk.E)
        
    def create_log_panel(self, parent, row, column=0, columnspan=1):
        """创建日志面板"""
        # 日志面板框架
        log_frame = ttk.LabelFrame(parent, text="📝 处理日志", style='Custom.TLabelframe', padding="15")
        log_frame.grid(row=row, column=column, columnspan=columnspan, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 15), padx=(5, 0))
        log_frame.columnconfigure(0, weight=1)
        log_frame.rowconfigure(0, weight=1)
        parent.rowconfigure(row, weight=1)
        
        # 日志文本框 - 铺满整个面板
        self.log_text = scrolledtext.ScrolledText(log_frame, height=12, width=100,
                                                 font=('Consolas', 9),
                                                 wrap=tk.WORD,
                                                 bg=self.colors['surface'],
                                                 fg=self.colors['text'],
                                                 insertbackground=self.colors['text'],
                                                 selectbackground=self.colors['primary'],
                                                 selectforeground='white',
                                                 relief='solid',
                                                 borderwidth=1)
        self.log_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        
    def setup_logging(self):
        """设置日志记录"""
        # 创建日志处理器
        self.log_handler = LogHandler(self.log_text, self.update_log_stats)
        self.logger = logging.getLogger('gui')
        self.logger.setLevel(logging.INFO)
        self.logger.addHandler(self.log_handler)
        
    def browse_input_dir(self):
        """浏览输入目录"""
        directory = filedialog.askdirectory(title="选择报告输入目录")
        if directory:
            self.input_dir_var.set(directory)
            self.refresh_file_stats()
            
    def browse_output_dir(self):
        """浏览输出目录"""
        directory = filedialog.askdirectory(title="选择报告输出目录")
        if directory:
            self.output_dir_var.set(directory)
            self.refresh_file_stats()
    
    def refresh_file_stats(self):
        """刷新文件统计信息"""
        input_dir = self.input_dir_var.get().strip()
        if not input_dir or not Path(input_dir).exists():
            self.file_stats_label.config(text="未选择目录")
            return
            
        try:
            # 统计Word文档数量
            doc_files = list(Path(input_dir).glob("*.doc*"))
            doc_count = len(doc_files)
            
            # 统计其他文件
            all_files = list(Path(input_dir).iterdir())
            other_files = [f for f in all_files if f.is_file() and not f.name.endswith(('.doc', '.docx'))]
            other_count = len(other_files)
            
            stats_text = f"Word文档: {doc_count}个"
            if other_count > 0:
                stats_text += f" | 其他文件: {other_count}个"
                
            self.file_stats_label.config(text=stats_text)
            
        except Exception as e:
            self.file_stats_label.config(text=f"统计失败: {str(e)}")
    
    def clear_system_prompt(self):
        """清空系统提示词"""
        self.system_prompt_text.delete('1.0', tk.END)
        self.logger.info("已清空系统提示词")
    
    def reset_system_prompt(self):
        """重置系统提示词为默认值"""
        default_prompt = """你是一位专业的实验报告批改老师。请根据以下标准对学生的实验报告进行评分：

评分标准（总分100分）：
1. 实验准备（25分）：实验目的明确、原理清晰、步骤完整
2. 实验内容（40分）：实验过程详细、数据记录准确、操作规范
3. 实验小结（25分）：结果分析深入、问题讨论充分、结论合理
4. 文档格式（10分）：排版整洁、图表清晰、语言规范

请严格按照以下格式输出评分结果：
{
    "score": 85,
    "comments": "实验准备充分，实验过程详细，但结果分析可以更深入。建议在实验小结中增加对实验误差的分析。"
}

注意：
- 总分必须是四项分数之和
- 评语要具体指出优点和不足
- 给出改进建议"""
        
        self.system_prompt_text.delete('1.0', tk.END)
        self.system_prompt_text.insert('1.0', default_prompt)
        self.logger.info("已重置系统提示词为默认值")
            
            
    
    def update_log_stats(self):
        """更新日志统计信息"""
        try:
            content = self.log_text.get('1.0', tk.END).strip()
            if not content:
                self.log_stats_label.config(text="")
                return
                
            lines = content.split('\n')
            line_count = len([line for line in lines if line.strip()])
            
            # 计算字符数
            char_count = len(content)
            
            # 更新统计标签
            stats_text = f"行数: {line_count} | 字符: {char_count}"
            
        except Exception:
            pass
        
    def start_processing(self):
        """开始批改处理"""
        if self.is_processing:
            return
            
        # 验证输入
        if not self.validate_inputs():
            return
            
        # 更新配置
        self.update_config()
        
        # 开始处理
        self.is_processing = True
        self.start_button.config(state='disabled')
        self.stop_button.config(state='normal')
        
        # 在新线程中处理
        self.processing_thread = threading.Thread(target=self.process_documents)
        self.processing_thread.daemon = True
        self.processing_thread.start()
        
    def stop_processing(self):
        """停止批改处理"""
        self.is_processing = False
        self.start_button.config(state='normal')
        self.stop_button.config(state='disabled')
        self.logger.info("用户停止了批改处理")
        
    def validate_inputs(self) -> bool:
        """验证输入参数"""
        if not self.input_dir_var.get().strip():
            messagebox.showerror("错误", "请选择报告输入目录")
            return False
            
        if not self.output_dir_var.get().strip():
            messagebox.showerror("错误", "请选择报告输出目录")
            return False
            
        if not Path(self.input_dir_var.get()).exists():
            messagebox.showerror("错误", "报告输入目录不存在")
            return False
            
        return True
        
    def update_config(self):
        """更新配置"""
        self.config.update({
            'input_directory': self.input_dir_var.get(),
            'output_directory': self.output_dir_var.get(),
            'comment_author': self.comment_author_var.get(),
            'required_sections': [s.strip() for s in self.required_sections_text.get('1.0', tk.END).strip().split('\n') if s.strip()],
            'system_prompt': self.system_prompt_text.get('1.0', tk.END).strip(),
            'model_type': self.model_type_var.get(),
            'api_key': self.api_key_var.get(),
            'base_url': self.base_url_var.get()
        })
        
    def process_documents(self):
        """处理文档（在后台线程中运行）"""
        try:
            import time
            start_time = time.time()
            self.logger.info("开始批改处理...")
            
            # 更新状态
            self.status_label.config(text="状态: 处理中")
            self.time_label.config(text="开始时间: " + time.strftime("%H:%M:%S"))
            
            input_dir = Path(self.input_dir_var.get())
            output_dir = Path(self.output_dir_var.get())
            
            # 创建输出目录
            setup_output_directory(output_dir)
            
            # 初始化处理器
            processor = DocumentProcessor()
            excel_recorder = ExcelRecorder(output_dir, self.logger)
            
            # 获取文档文件
            doc_files = list(input_dir.glob("*.doc*"))
            total_files = len(doc_files)
            
            if total_files == 0:
                self.logger.warning("未找到任何Word文档")
                return
                
            self.logger.info(f"找到 {total_files} 个文档待处理")
            
            # 处理每个文档
            for i, doc_file in enumerate(doc_files):
                if not self.is_processing:
                    break
                    
                try:
                    # 更新进度
                    progress = (i / total_files) * 100
                    self.progress_var.set(progress)
                    self.progress_label.config(text=f"🔄 正在处理: {doc_file.name}")
                    self.stats_label.config(text=f"📊 进度: {i+1}/{total_files} ({progress:.1f}%)")
                    
                    # 提取学生信息
                    filename = doc_file.stem
                    student_id = filename.split('_')[0].split('-')[0].split(' ')[0]
                    student_name = filename.split('_', 1)[1] if '_' in filename else ''
                    
                    # 设置日志记录器
                    processor.set_logger(self.logger)
                    
                    # 批改文档
                    result = processor.grade_document(
                        doc_file, 
                        student_id, 
                        student_name, 
                        self.config['required_sections']
                    )
                    
                    # 记录结果
                    excel_recorder.add_result(
                        student_id=result['student_id'],
                        student_name=result['student_name'],
                        score=result['score'],
                        comments=result['comments']
                    )
                    
                    # 保存结果
                    output_file = output_dir / f"{filename}.docx"
                    processor.save_results(
                        result['comment_text'], 
                        output_file, 
                        doc_file, 
                        self.config['comment_author']
                    )
                    
                    self.logger.info(f"完成处理: {filename} - 得分: {result['score']}")
                    
                except Exception as e:
                    self.logger.error(f"处理文档 {doc_file.name} 时出错: {str(e)}")
                    continue
            
            # 保存Excel结果
            if self.is_processing:
                excel_recorder.save_to_excel()
                
                # 计算处理时间
                end_time = time.time()
                elapsed_time = end_time - start_time
                hours = int(elapsed_time // 3600)
                minutes = int((elapsed_time % 3600) // 60)
                seconds = int(elapsed_time % 60)
                
                if hours > 0:
                    time_str = f"{hours}小时{minutes}分钟{seconds}秒"
                elif minutes > 0:
                    time_str = f"{minutes}分钟{seconds}秒"
                else:
                    time_str = f"{seconds}秒"
                
                # 获取统计信息
                stats = excel_recorder.get_statistics()
                self.logger.info(f"批改完成! 共处理 {stats['total_students']} 个学生")
                self.logger.info(f"平均分: {stats['average_score']}")
                self.logger.info(f"最高分: {stats['highest_score']}")
                self.logger.info(f"最低分: {stats['lowest_score']}")
                self.logger.info(f"总耗时: {time_str}")
                
                # 更新进度
                self.progress_var.set(100)
                self.progress_label.config(text="✅ 批改完成!")
                self.stats_label.config(text=f"🎉 共处理 {stats['total_students']} 个学生，平均分: {stats['average_score']}")
                self.status_label.config(text="状态: 完成")
                self.time_label.config(text=f"耗时: {time_str}")
            
        except Exception as e:
            self.logger.error(f"批改过程中发生错误: {str(e)}")
            messagebox.showerror("错误", f"批改过程中发生错误: {str(e)}")
        finally:
            self.is_processing = False
            self.start_button.config(state='normal')
            self.stop_button.config(state='disabled')
            # 重置状态显示
            if not self.is_processing:
                self.status_label.config(text="状态: 空闲")
                self.time_label.config(text="")
            
    def toggle_theme(self):
        """切换主题"""
        self.current_theme = "dark" if self.current_theme == "light" else "light"
        self.setup_styles()
        self.logger.info(f"已切换到{self.current_theme}主题")
        
        # 更新主题切换按钮文本
        theme_text = "🌙 深色主题" if self.current_theme == "light" else "☀️ 浅色主题"
        # 这里需要重新创建控制面板来更新按钮文本，或者存储按钮引用
        self.refresh_theme_button()
    
    def refresh_theme_button(self):
        """刷新主题切换按钮"""
        # 这个方法会在主题切换后更新按钮文本
        # 由于按钮是在create_control_panel中创建的，我们需要重新创建整个控制面板
        # 或者存储按钮引用并在主题切换时更新
        pass
    
    def open_analysis_window(self):
        """打开分析报告窗口"""
        try:
            output_dir = self.output_dir_var.get()
            if not output_dir:
                messagebox.showerror("错误", "请先选择输出目录")
                return
                
            # 打开分析窗口，传递当前主题
            open_analysis_window(self.root, output_dir, self.current_theme)
            self.logger.info("已打开成绩分析报告窗口")
            
        except Exception as e:
            messagebox.showerror("错误", f"打开分析窗口失败: {str(e)}")
            self.logger.error(f"打开分析窗口失败: {str(e)}")


class LogHandler(logging.Handler):
    """自定义日志处理器，将日志输出到文本框"""
    
    def __init__(self, text_widget, update_stats_callback=None):
        super().__init__()
        self.text_widget = text_widget
        self.update_stats_callback = update_stats_callback
        
    def emit(self, record):
        """发送日志记录到文本框"""
        try:
            msg = self.format(record)
            self.text_widget.insert(tk.END, msg + '\n')
            self.text_widget.see(tk.END)
            
            # 更新统计信息
            if self.update_stats_callback:
                self.text_widget.after_idle(self.update_stats_callback)
        except Exception:
            pass


class FeedbackSummaryGenerator:
    """反馈意见汇总生成器"""
    
    def __init__(self):
        self.logger = logging.getLogger('feedback_summary')
        
    def generate_summary(self, excel_file: Path, output_dir: Path) -> Path:
        """生成反馈意见汇总"""
        import pandas as pd
        from collections import Counter
        
        # 读取Excel文件
        df = pd.read_excel(excel_file)
        
        # 生成汇总报告
        summary_content = []
        summary_content.append("=" * 50)
        summary_content.append("实验报告批改反馈意见汇总")
        summary_content.append("=" * 50)
        summary_content.append(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        summary_content.append(f"总学生数: {len(df)}")
        summary_content.append("")
        
        # 成绩统计
        scores = df['成绩'].tolist()
        summary_content.append("成绩统计:")
        summary_content.append(f"  平均分: {sum(scores)/len(scores):.2f}")
        summary_content.append(f"  最高分: {max(scores)}")
        summary_content.append(f"  最低分: {min(scores)}")
        summary_content.append("")
        
        # 分数分布
        score_ranges = [(score // 10) * 10 for score in scores]
        score_dist = Counter(score_ranges)
        summary_content.append("分数分布:")
        for score_range in sorted(score_dist.keys()):
            count = score_dist[score_range]
            percentage = (count / len(scores)) * 100
            summary_content.append(f"  {score_range}-{score_range+9}分: {count}人 ({percentage:.1f}%)")
        summary_content.append("")
        
        # 常见问题汇总
        summary_content.append("常见问题汇总:")
        common_issues = self.analyze_common_issues(df['评语'].tolist())
        for i, issue in enumerate(common_issues, 1):
            summary_content.append(f"  {i}. {issue}")
        summary_content.append("")
        
        # 改进建议
        summary_content.append("总体改进建议:")
        summary_content.append("  1. 建议学生注意文档结构的完整性")
        summary_content.append("  2. 加强实验内容的详细描述")
        summary_content.append("  3. 重视实验小结的反思内容")
        summary_content.append("  4. 注意文档格式的规范性")
        
        # 保存汇总文件
        summary_file = output_dir / f"反馈意见汇总_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
        with open(summary_file, 'w', encoding='utf-8') as f:
            f.write('\n'.join(summary_content))
            
        return summary_file
        
    def analyze_common_issues(self, comments: list) -> list:
        """分析常见问题"""
        # 简单的关键词分析
        issue_keywords = {
            '结构不完整': ['结构', '缺失', '不完整'],
            '内容不够详细': ['内容', '详细', '不够'],
            '格式不规范': ['格式', '规范', '排版'],
            '小结不充分': ['小结', '反思', '总结']
        }
        
        issues = []
        for issue_type, keywords in issue_keywords.items():
            count = sum(1 for comment in comments if any(keyword in comment for keyword in keywords))
            if count > 0:
                issues.append(f"{issue_type}: {count}人")
                
        return issues[:5]  # 返回前5个最常见的问题


def main():
    """主函数"""
    root = tk.Tk()
    app = MainWindow(root)
    root.mainloop()


if __name__ == "__main__":
    main()
